// eee.Sheffield.PZ.Imaging
//
// Copyright ?Ping Zou, 2007
// sg71.cherub@gmail.com


using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections.Generic;
using eee.Sheffield.PZ.Math;
using System.Collections;

namespace eee.Sheffield.PZ.Imaging
{
    // Liu&Sun deletion scheme
    public class LiuSunDeletion
    {
        private LiuSunTrackResult _trackResult;

        public LiuSunDeletion(LiuSunTrackResult trackResult)
        {
            _trackResult = trackResult;
        }

        public void Apply(ref Bitmap srcImage)
        {
            int width = srcImage.Width;
            int height = srcImage.Height;

            int trackResultLength = _trackResult.Count;

            // for each step
            for (int i = 1; i < trackResultLength; i++)
            {                
                PZPoint pLiM1 = _trackResult.EdgePoint1Array[i - 1];
                PZPoint pLi = _trackResult.EdgePoint1Array[i];
                PZPoint pRiM1 = _trackResult.EdgePoint2Array[i - 1];
                PZPoint pRi = _trackResult.EdgePoint2Array[i];
                byte backgroundLevel = Convert.ToByte(_trackResult.BackgroundLevelArray[i]);

                // find search region, the smallest rectangle that contains the quadrilateral
                int xMin, xMax, yMin, yMax;
                double[] xCoordinates = new double[4];
                xCoordinates[0] = pLiM1.x;
                xCoordinates[1] = pLi.x;
                xCoordinates[2] = pRiM1.x;
                xCoordinates[3] = pRi.x;
                Array.Sort(xCoordinates);
                xMin = (int)xCoordinates[0];
                xMax = (int)xCoordinates[3];

                double[] yCoordinates = new double[4];
                yCoordinates[0] = pLiM1.y;
                yCoordinates[1] = pLi.y;
                yCoordinates[2] = pRiM1.y;
                yCoordinates[3] = pRi.y;
                Array.Sort(yCoordinates);
                yMin = (int)yCoordinates[0];
                yMax = (int)yCoordinates[3];

                // for each pixel in the search region
                for (int x = xMin; x <= xMax; x++)
                {
                    for (int y = yMin; y <= yMax; y++)
                    {
                        if (x >= 0 && x < width && y >= 0 && y < height)
                        {
                            PZPoint p = new PZPoint(x, y);
                            // DLL
                            double LLax = p.x - pLi.x;
                            double LLay = p.y - pLi.y;
                            double LLbx = pLiM1.x - pLi.x;
                            double LLby = pLiM1.y - pLi.y;
                            double DLL = LLax * LLby - LLay * LLbx;
                            // DLR
                            double LRax = p.x - pLiM1.x;
                            double LRay = p.y - pLiM1.y;
                            double LRbx = pRiM1.x - pLiM1.x;
                            double LRby = pRiM1.y - pLiM1.y;
                            double DLR = LRax * LRby - LRay * LRbx;
                            // DRR
                            double RRax = p.x - pRiM1.x;
                            double RRay = p.y - pRiM1.y;
                            double RRbx = pRi.x - pRiM1.x;
                            double RRby = pRi.y - pRiM1.y;
                            double DRR = RRax * RRby - RRay * RRbx;
                            // DRL
                            double RLax = p.x - pRi.x;
                            double RLay = p.y - pRi.y;
                            double RLbx = pLi.x - pRi.x;
                            double RLby = pLi.y - pRi.y;
                            double DRL = RLax * RLby - RLay * RLbx;

                            if (DRL * DLR > 0 && DRR * DLL > 0)
                                srcImage.SetPixel(x, y, Color.FromArgb(backgroundLevel, backgroundLevel, backgroundLevel));
                        }
                    } // for y
                } // for x
            } // for i

        } // Apply()
    }
}
